package gui;

import java.awt.Color;
import java.util.HashMap;
import java.util.Map;

import processing.core.PApplet;
import processing.core.PFont;
import core.College;
import core.HubwayStation;
import core.MBTAStation;
import core.Trip;


public class VisualAnalytics extends PApplet {

	// -----------------------------------------------------------------
	// Atributos
	// -----------------------------------------------------------------
	
	private Map<Integer, HubwayStation> hubwayStations;
	private Map<Integer, College> colleges;
	private Map<Integer, MBTAStation> mbtaStations;
	
	private Map<Integer, Point> pointsHubwayStations;
	private Map<Integer, Point> pointsColleges;
	private Map<Integer, Point> pointsMbtaStations;
	
	/**
	 * Valores maximos y minimos para latitud y longitud de la Tierra
	 */
	private float dataLatMin;
	private float dataLatMax;
	private float dataLonMin;
	private float dataLonMax;

	/**
	 * Variables para establecer el tamanio del lienzo 
	 */
	private int xSize;
	private int ySize;

//	String dataHubwayTrips [][];
//	String dataColleges [][];
//	String dataHubwayStations [][];
//	String dataMBTAStations [][];

	private int overRadiusPoints;

	private PFont fontBig;
	
	private int selectedHubwayStation;
	
	//Buttons
	private ControlButton buttonHubwayStations;
	private ControlButton buttonMBTASubway;
	private ControlButton buttonColleges;
	private ControlButton buttonAll;

	public void setup() {

		xSize = displayWidth;
		ySize = displayHeight;
		
		// Initialize data
		hubwayStations = new HashMap<Integer, HubwayStation>();
		colleges = new HashMap<Integer, College>();
		mbtaStations = new HashMap<Integer, MBTAStation>();
		
		pointsHubwayStations = new HashMap<Integer, Point>();
		pointsColleges = new HashMap<Integer, Point>();
		pointsMbtaStations = new HashMap<Integer, Point>();
		
		fontBig = loadFont("Arial-Black-48.vlw");
		
		buttonHubwayStations = new ControlButton(this, xSize/2 -30 , 50, Color.BLUE.getRGB());
		buttonHubwayStations.setText("Hubway Stations", 10, ySize - 150, fontBig);
		buttonColleges = new ControlButton(this, xSize/2 -30, 100, Color.RED.getRGB());
		buttonColleges.setText("Colleges", 10, ySize - 150, fontBig);
		buttonMBTASubway = new ControlButton(this, xSize/2 -30, 150, Color.MAGENTA.getRGB());
		buttonMBTASubway.setText("MBTA Stations", 10, ySize - 150, fontBig);
		buttonAll = new ControlButton(this, xSize/2 -30, 200, Color.BLACK.getRGB());
		
		selectedHubwayStation = -1;
		

		buttonAll.setSelected();
		buttonHubwayStations.setSelected();
		buttonColleges.setSelected();
		buttonMBTASubway.setSelected();

		dataLatMin = 42.2f;
		dataLatMax = 42.4f;
		dataLonMin = -71.2f;
		dataLonMax = -70.9f;

		overRadiusPoints = 5;

		size(xSize,ySize);
		smooth();
		noStroke();
		
		String rowsHubwayStations[] = loadStrings("Hubway_Stations_Data.csv"); //leo archivo de datos
		String[][] dataHubwayStations= new String [rowsHubwayStations.length][]; //Creo la matriz de datos
		for (int i=1; i< rowsHubwayStations.length; i++){
			String columns [] = rowsHubwayStations[i].split(";");
			dataHubwayStations[i]=columns; //Recorro la matriz y asigno los datos
			//println(data3[i][1]);
			int id = Integer.parseInt(columns[0]);
			float posLongitude = Float.parseFloat(columns[4]);
			float posLatitude = Float.parseFloat(columns[3]);
			String name = columns[2];
			String terminalName= columns[3];
			HubwayStation station = new HubwayStation(id, posLongitude, posLatitude, name, terminalName);
			hubwayStations.put(station.getId(), station);	
			
			float posX = map(station.getPosLongitude(), dataLonMin, dataLonMax, 0, xSize/2);
			float posY = map(station.getPosLatitude(), dataLatMin, dataLatMax, ySize, 0);
			
			Point p = new Point((int)posX, (int)posY, Color.BLUE.getRGB(), this);
			pointsHubwayStations.put(station.getId(), p);
		}

		String rowsHubwayTrips[] = loadStrings("Hubway_Trips.csv"); //leo archivo de datos
		String[][] dataHubwayTrips= new String [rowsHubwayTrips.length][]; //Creo la matriz de datos
		int corruptedData = 0;
		int missingColumns = 0;
		for (int i=1; i< rowsHubwayTrips.length; i++){
			String columns [] = rowsHubwayTrips[i].split(",");
			dataHubwayTrips[i]=columns; //Recorro la matriz y asigno los datos
			//println(data1[i][1]);
			
			if(columns.length == 12)
			{
				try {
					int id = Integer.parseInt(columns[0]);
					String startDate = columns[3];
					String endDate = columns[5];
					int duration = Integer.parseInt(columns[2]);
					String bikeNumber = columns[7];
					int subscriptionType = Trip.getSubscritionTypeFromString(columns[8]);
					int birthDate = Integer.parseInt(columns[10]);
					int gender = Trip.getGenderFromString(columns[11]);
					Trip trip = new Trip(id, startDate, endDate, duration, bikeNumber, subscriptionType, birthDate, gender);
					int startStation = Integer.parseInt(columns[4]);
					hubwayStations.get(startStation).addOutgoingTrip(trip);
					int endStation = Integer.parseInt(columns[6]);
					hubwayStations.get(endStation).addIncomingTrip(trip);
				} catch (NumberFormatException e) {
					corruptedData++;
				}
			}
			else
			{
				missingColumns++;
			}
		}

		for(Map.Entry<Integer, HubwayStation> entry: hubwayStations.entrySet())
		{
			entry.getValue().calculateMeans();
		}
		System.err.println("Corrupted data: " + corruptedData + " registers out of " + rowsHubwayTrips.length);
		System.err.println("Missing columns: " + missingColumns + " registers out of " + rowsHubwayTrips.length);
		
		String rowsColleges[] = loadStrings("Colleges_Data.csv"); //leo archivo de datos
		String[][] dataColleges= new String [rowsColleges.length][]; //Creo la matriz de datos
		for (int i=1; i< rowsColleges.length; i++){
			String columns [] = rowsColleges[i].split(",");
			dataColleges[i]=columns; //Recorro la matriz y asigno los datos
			//println(data2[i][1]);
			int id = Integer.parseInt(columns[0]);
			float posLongitude = Float.parseFloat(columns[2]);
			float posLatitude = Float.parseFloat(columns[1]);
			String name = columns[3];
			College college = new College(id, posLongitude, posLatitude, name);
			colleges.put(college.getId(), college);
			
			float posX = map(college.getPosLongitude(), dataLonMin, dataLonMax, 0, xSize/2);
			float posY = map(college.getPosLatitude(), dataLatMin, dataLatMax, ySize, 0);
			Point p = new Point((int)posX, (int)posY, Color.RED.getRGB(), this);
			pointsColleges.put(college.getId(), p);
		}
		
		String rowsMBTAStations[] = loadStrings("MBTA_Subway_Stations_Data.csv"); //leo archivo de datos
		String[][] dataMBTAStations= new String [rowsMBTAStations.length][]; //Creo la matriz de datos
		for (int i=1; i< rowsMBTAStations.length; i++){
			String columns [] = rowsMBTAStations[i].split(";");
			dataMBTAStations[i]=columns; //Recorro la matriz y asigno los datos
			//println(data4[i][1]);
			
			int id = Integer.parseInt(columns[0]);
			float posLongitude = Float.parseFloat(columns[4]);
			float posLatitude = Float.parseFloat(columns[3]);
			String name = columns[1];
			MBTAStation mbtaStation = new MBTAStation(id, posLongitude, posLatitude, name);
			mbtaStations.put(mbtaStation.getId(), mbtaStation);
			
			float posX = map(mbtaStation.getPosLongitude(), dataLonMin, dataLonMax, 0, xSize/2);
			float posY = map(mbtaStation.getPosLatitude(), dataLatMin, dataLatMax, ySize, 0);
			Point p = new Point((int) posX, (int)posY, Color.MAGENTA.getRGB(), this);
			pointsMbtaStations.put(mbtaStation.getId(), p);
		}

	}

	public void draw() {
		//Clean canvas
		background(240,240,240);

		//Create secondary "canvas"
		fill(0,0,0);
		stroke(0,0,0);
		rect(xSize/2,0,xSize, ySize);

		fill(100,100,100);
		stroke(100,100,100);
		rect(xSize/2 - 60 , 0 , 60, ySize);

		if(buttonHubwayStations.overPoint())
		{
			buttonHubwayStations.setSelected();
			buttonColleges.setUnselected();
			buttonMBTASubway.setUnselected();
			buttonAll.setUnselected();
		}

		if(buttonHubwayStations.isSelected() && !buttonAll.isSelected())
		{
			buttonHubwayStations.drawText();
		}
		buttonHubwayStations.drawButton();

		if (buttonColleges.overPoint())
		{
			buttonHubwayStations.setUnselected();
			buttonColleges.setSelected();
			buttonMBTASubway.setUnselected();
			buttonAll.setUnselected();
		}
		
		if(buttonColleges.isSelected() && !buttonAll.isSelected())
		{
			buttonColleges.drawText();
		}
		buttonColleges.drawButton();

		if (buttonMBTASubway.overPoint())
		{
			buttonHubwayStations.setUnselected();
			buttonColleges.setUnselected();
			buttonMBTASubway.setSelected();
			buttonAll.setUnselected();
		}
		
		if(buttonMBTASubway.isSelected() && !buttonAll.isSelected())
		{
			buttonMBTASubway.drawText();
		}
		buttonMBTASubway.drawButton();

		if (buttonAll.overPoint() || buttonAll.isSelected())
		{
			buttonHubwayStations.setUnselected();
			buttonColleges.setUnselected();
			buttonMBTASubway.setUnselected();
			buttonAll.setSelected();
			
			textFont(fontBig, 20);
			fill(0,0,0);
			text("Hubway Stations", 8, ySize - 182);
			fill(0,0,255);
			text("Hubway Stations", 10, ySize - 180);
			fill(0,0,0);
			text("Colleges", 8, ySize - 152);
			fill(255,0,0);
			text("Colleges", 10, ySize - 150);
			fill(0,0,0);
			text("MBTA Stations", 8, ySize - 122);
			fill(255,0,255);
			text("MBTA Stations", 10, ySize - 120);
			fill(0,0,0);
		}
		buttonAll.drawButton();

		textFont(fontBig, 15);
		for(Map.Entry<Integer, Point> entryColleges : pointsColleges.entrySet())
		{
			Point p = entryColleges.getValue();
			if(buttonColleges.isSelected())
			{
				if(p.overPoint())
				{
					p.setSelected();
				}
				else
				{
					p.setUnselected();
					p.setHiglighted();
				}
			}
			else
			{
				p.setUnhighlighted();
			}
			p.drawPoint();
		}

//		boolean stationChosen = false;
//		for (int r = 1; r < dataHubwayStations.length; r++){
//			float posX = map(parseFloat(dataHubwayStations[r][4]),dataLonMin,dataLonMax,0,xSize/2);
//			float posY = map(parseFloat(dataHubwayStations[r][3]),dataLatMin,dataLatMax,ySize,0);
//
//			stroke(0,0,255);
//			if(buttonHubwayStations.isSelected())
//			{
//				fill(0,0,255);
//
//				if (overPoint(posX,posY, overRadiusPoints)){
//					fill(0,0,255);
//					ellipse (posX, posY, 10,10);
//					fill (0,0,0);
//					text(dataHubwayStations[r][2],posX + 10, posY + 10);
//					fill(0,0,255);
//					selectedHubwayStation = Integer.parseInt(dataHubwayStations[r][0]);
//					stationChosen = true;
//				} 
//			}
//			else
//			{
//				noFill();
//			}
//
//			ellipse (posX, posY, 5,5);	
//		}
//		
//		if(!stationChosen)
//		{
//			selectedHubwayStation = -1;
//		}
//
//		for (int r = 1; r < dataMBTAStations.length; r++){
//			float posX = map(parseFloat(dataMBTAStations[r][4]),dataLonMin,dataLonMax,0,xSize/2);
//			float posY = map(parseFloat(dataMBTAStations[r][3]),dataLatMin,dataLatMax,ySize,0);
//
//			stroke(255, 0, 255);
//			if(buttonMBTASubway.isSelected())
//			{
//				fill(255, 0, 255);
//
//				if (overPoint(posX,posY, overRadiusPoints)){
//					fill(255, 0, 255);
//					ellipse (posX, posY, 10,10);
//					fill (0,0,0);
//					text(dataMBTAStations[r][1],posX + 10, posY + 10);
//					fill(255, 0, 255);
//				} 
//			}
//			else
//			{
//				noFill();
//			}
//
//			ellipse (posX, posY, 5,5);	
//
//		}
		
		
		
		//******************************************
		stroke(255,255,255);
		fill(255,255,255);
		int gap = xSize/8;
		text("Duraci�n", xSize/2 + gap, 150);
		text("Edad", xSize/2 + (2*gap), 150);
		text("Registrados", xSize/2 + (3*gap), 150);
		line(xSize/2 + gap, 200, xSize/2 + gap, ySize - 200);
		line(xSize/2 + (2*gap), 200, xSize/2 + (2*gap), ySize - 200);
		line(xSize/2 + (3*gap), 200, xSize/2 + (3*gap), ySize - 200);
		
		int lineLength = ySize - 400;
		
		if(selectedHubwayStation != -1)
		{
			HubwayStation hubwayStation = hubwayStations.get(selectedHubwayStation);
			int[] durations = hubwayStation.getOutgoingDurations();
			int[] ages = hubwayStation.getOutgoingBirthdates();
			int[] gender = hubwayStation.getOutgoingGenders();

			int minDuration = durations[0];
			int maxDuration = durations[1];
			int ageMin = 2013 - ages[1];
			int ageMax = 2013 - ages[0];
			
			text(minDuration, xSize/2 + gap - 10 , 190);
			text(maxDuration, xSize/2 + gap - 10, ySize - 180);
			
			text(ageMin, xSize/2 + (2*gap) - 10, 200);
			text(ageMax, xSize/2 + (2*gap) - 10, ySize - 180);
			
			text(durations.length + " outgoing trips", xSize/2 + gap, 100);

			for (int i = 2; i < durations.length ; i++){
				try {

					float yLineValueTrips = map((float)durations[i], minDuration, maxDuration, 200 , lineLength + 200);
					
					float currentAge = 2013 - ages[i];
					float yLineValueAge = map(currentAge, ageMin, ageMax, 200, lineLength + 200);
					

					stroke(255,255,255);
					strokeWeight(1);

					line(xSize/2 + gap, yLineValueTrips, xSize/2 + (2*gap), yLineValueAge);

					int medianValueTrip = hubwayStation.getOutgoingMeanDuration();
					float yLineMedianValueTrip = map((float)medianValueTrip, minDuration, maxDuration, 200 , lineLength + 200);
					float medianAge = 2013 - hubwayStation.getOutgoingMeanBirthdate();
					float yLineMedianValueAge = map(medianAge, ageMin, ageMax, 200, lineLength + 200);

					stroke(0,255,0);
					strokeWeight(1);
					line(xSize/2 + gap, yLineMedianValueTrip, xSize/2 + (2*gap), yLineMedianValueAge);
					fill(0,255,0);
					text(medianValueTrip, xSize/2 + gap, yLineMedianValueTrip);
					text((int)medianAge, xSize/2 + (2*gap), yLineMedianValueAge);
					
				} catch (Exception e) {

				}
			}
		}

	}
}




